home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / QuickTime / VDTextSample / VDTextSample.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-10  |  11.8 KB  |  520 lines  |  [TEXT/MMCC]

  1. /*
  2.     File:        VDTextSample.c
  3.     
  4.     Written by:    Larry Lai, DTS
  5.  
  6.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  7.  
  8.     This snippet shows you how to draw and erase text to the video
  9.     preview image without causing flickers on the screen. It only 
  10.     works with 'vdig's that support key color (Quadra 660AV, 840AV, 
  11.     630 and PowerMac 6100/7100/8100 AVs). Read "Inside Macintosh: 
  12.     QuickTime Component" Video Digitizer Component chapter for more 
  13.     information.
  14.     
  15.     Change History (most recent first):
  16.  
  17.         <1>    2/22/95 LL    create first working version.
  18.             3/10/95    LL    add about-this-app box.
  19.     To Do:     
  20.     
  21. */
  22.  
  23. /* HEADER FILES */
  24.  
  25. #include    <Types.h>
  26. #include    <Memory.h>
  27. #include    <QuickDraw.h>
  28. #include    <Palettes.h>
  29. #include    <QDOffscreen.h>
  30. #include    <Errors.h>
  31. #include    <Fonts.h>
  32. #include    <Dialogs.h>
  33. #include    <Windows.h>
  34. #include    <Menus.h>
  35. #include    <Events.h>
  36. #include    <OSUtils.h>
  37. #include    <Resources.h>
  38. #include    <ToolUtils.h>
  39. #include    <AppleEvents.h>
  40. #include    <GestaltEqu.h>
  41. #include    <Processes.h>
  42. #include    <Aliases.h>
  43. #include    <MixedMode.h>
  44. #include    <LowMem.h>
  45. #include     <Sound.h>
  46.  
  47. #include    <Movies.h>
  48. #include    <QuickTimeComponents.h>
  49. #include     <ImageCompression.h>
  50.  
  51. /* DEFINES */
  52.  
  53. #define    appleID            128            
  54. #define    appleMenu        0
  55. #define    aboutMeCommand    1
  56.  
  57. #define    fileID            129
  58. #define textCommand        1
  59. #define    quitCommand     3
  60.  
  61. #define    aboutMeDLOG        128
  62. #define    okButton        1
  63.  
  64. #define    kSoundID        128
  65. #define    kBruceIconItem    4
  66.  
  67. /* FUNCTION PROTOTYPES*/
  68.  
  69. void CheckError(OSErr error, Str255 displayString);
  70. Boolean    IsQuickTimeInstalled(void);
  71. void initialize(void);
  72. WindowPtr makeWindow(void);
  73. SeqGrabComponent makeSequenceGrabber (WindowPtr aWindow);
  74. void makeGrabChannels (    SeqGrabComponent anSG,
  75.                         SGChannel *videoChannel,
  76.                         SGChannel *soundChannel,
  77.                         const Rect *bounds, Boolean willRecord);
  78. void EraseVideo(SeqGrabComponent aSG, WindowPtr aWindow, SGChannel theChannel);
  79. void ShowAboutMeDialog(void);
  80. void DoCommand(long mResult);
  81. pascal Boolean MyFilter(DialogPtr inputDialog, EventRecord *myDialogEvent, short *theDialogItem);
  82.  
  83. /* GLOBALS */
  84.  
  85. Boolean    done = false;
  86. Boolean showString = true;
  87. Boolean    menuKey = false;
  88. MenuHandle mymenu0, mymenu1;
  89. WindowPtr    theWindow;
  90. SeqGrabComponent    theSG;
  91. SGChannel    videoChannel, soundChannel;
  92.  
  93. /* FUNCTIONS */
  94.  
  95. void CheckError(OSErr error, Str255 displayString)
  96. {
  97.     if(error == noErr) return;
  98.     if(displayString[0] > 0)
  99.         DebugStr(displayString);
  100.     ExitToShell();
  101. }
  102.  
  103. Boolean    IsQuickTimeInstalled(void)
  104. {
  105.     short     error;
  106.     long    result;
  107.     
  108.     error = Gestalt(gestaltQuickTime, &result);
  109.     return    (error == noErr);
  110. }
  111.  
  112. void ShowAboutMeDialog(void)
  113. {
  114.     GrafPtr savePort;
  115.     DialogPtr theDialog;
  116.     Handle    theSound;
  117.     short itemHit;
  118.  
  119.     GetPort(&savePort);
  120.     theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) - 1);
  121.     SetPort(theDialog);
  122.  
  123.     do
  124.     {
  125.         ModalDialog((ModalFilterProcPtr) MyFilter, &itemHit);
  126.  
  127.         switch(itemHit){
  128.             case kBruceIconItem:
  129.                 /* don't mess with Bruce */
  130.                 theSound = GetResource('snd ', kSoundID);
  131.                     if (theSound != nil) {
  132.                     SndPlay(nil, (SndListHandle)theSound, false);
  133.                     ReleaseResource(theSound);
  134.                 }
  135.                   break;
  136.                 
  137.         }
  138.  
  139.     } while (itemHit != okButton);
  140.  
  141.     CloseDialog(theDialog);
  142.  
  143.     SetPort(savePort);
  144.     return;
  145. }
  146.  
  147. // True confession: this was stolen from C.K's "DialogBits.c".
  148. pascal Boolean MyFilter(DialogPtr inputDialog, EventRecord *myDialogEvent, short *theDialogItem)
  149. {
  150.     Rect tempRect;
  151.     short tempItem;
  152.     Handle tempHandle;
  153.     Point tempPoint;
  154.     Point mousePoint;
  155.     Boolean hiLit = false;
  156.     Boolean returnVal = false;
  157.  
  158.     if (myDialogEvent->what == mouseDown) {
  159.         mousePoint = (myDialogEvent->where);
  160.         GlobalToLocal(&mousePoint);
  161.         /* First see if we're in Bruce */
  162.         GetDItem(inputDialog, kBruceIconItem, &tempItem, &tempHandle, &tempRect);
  163.         if (PtInRect(mousePoint, &tempRect)) {
  164.             /* invert my icon, and track it whilst the user holds the mouse down */
  165.             InvertRect(&tempRect);
  166.             hiLit = true;
  167.             while (StillDown()) {
  168.                 GetMouse(&tempPoint);                       /* returns point in local coords */
  169.                 if (PtInRect(tempPoint, &tempRect)) {
  170.                     /* in the rect.  See if it's hilighted or not */
  171.                     if (hiLit == false) {
  172.                         hiLit = true;
  173.                         InvertRect(&tempRect);
  174.                     }
  175.                 } else {
  176.                     /* not in the rectangle.  If it's hilit, get rid of that */
  177.                     if (hiLit == true) {
  178.                         hiLit = false;
  179.                         InvertRect(&tempRect);
  180.                     }
  181.                 }
  182.             }
  183.             if (hiLit == true) {
  184.                 /* if it's still hilited when the mouse comes up, then that means the */
  185.                 /* user stayed in and wants to take this icon action */
  186.                 InvertRect(&tempRect);                      /* clear the hiliting if it's still lit */
  187.                 *theDialogItem = kBruceIconItem;
  188.                 returnVal = true;                           /* telling the Dialog Manager we handled it, pass item back */
  189.             }
  190.         } 
  191.     }
  192.     return returnVal;
  193. }
  194.  
  195.  
  196. void initialize(void)
  197.     OSErr    err;
  198.     short    i;
  199.     
  200.     InitGraf (&qd.thePort);
  201.     InitFonts();
  202.     InitWindows();
  203.     InitMenus();
  204.     TEInit();
  205.     InitDialogs(nil);
  206.     MaxApplZone();
  207.     
  208.     for (i = 0; i<=10; i++)
  209.         MoreMasters();
  210.     
  211.     if(!IsQuickTimeInstalled())
  212.         CheckError(-1, "\pPlease install QuickTime and try again.");
  213.         
  214.     err = EnterMovies();
  215.     CheckError(err, "\pUnable to initialize Movie Toolbox.");
  216.     
  217.         /*    Set up menus.    */
  218.     mymenu0 = GetMenu(appleID);
  219.     AddResMenu(mymenu0, 'DRVR');
  220.     InsertMenu(mymenu0, 0);
  221.     mymenu1 = GetMenu(fileID);
  222.     InsertMenu(mymenu1, 0);
  223.     DrawMenuBar();
  224. }
  225.  
  226. WindowPtr makeWindow(void)
  227. {
  228.     WindowPtr     aWindow;
  229.     Rect         windowRect = {0, 0, 240, 320};
  230.     Rect        bestRect;
  231.     
  232.     /* figure out the best monitor for the window */
  233.     GetBestDeviceRect (nil, &bestRect);
  234.     
  235.     /* put the window in the top left corner of that monitor */
  236.     OffsetRect(&windowRect, bestRect.left + 10, bestRect.top + 50);
  237.     
  238.     /* create the window */
  239.     aWindow = NewCWindow(nil, &windowRect, "\pPreviewer",
  240.                         true, noGrowDocProc, (WindowPtr)-1,
  241.                         true, 0);
  242.             
  243.     /* and set the port to the new window */
  244.     SetPort(aWindow);
  245.     
  246.     return aWindow;
  247.     
  248. }
  249.  
  250. main (void)
  251. {
  252.     OSErr        err = noErr;
  253.     char        key;
  254.  
  255.     initialize();
  256.     theWindow = makeWindow();
  257.     theSG = makeSequenceGrabber(theWindow);
  258.     if(!theSG) return;
  259.     
  260.     makeGrabChannels(theSG, &videoChannel, &soundChannel, 
  261.                     &theWindow->portRect, false);
  262.     
  263.     if((videoChannel == nil) && (soundChannel == nil))
  264.         CheckError(err, "\pCan't start preview");
  265.         
  266.     err = SGStartPreview(theSG);
  267.     CheckError(err, "\pCan't start preview");
  268.     
  269.     while(!done) {
  270.         ICMAlignmentProcRecord alignProc;
  271.         short    part;
  272.         WindowPtr    whichWindow;
  273.         EventRecord    theEvent;
  274.         
  275.         GetNextEvent(everyEvent, &theEvent);
  276.         
  277.         switch(theEvent.what) {
  278.             case nullEvent: /*give the sequence grabber time */
  279.                 err = SGIdle (theSG);
  280.                 if(err ) done = true;
  281.                 break;
  282.                 
  283.             case updateEvt: 
  284.                 if(theEvent.message == (long) theWindow) {
  285.  
  286.                         /* inform the sequesnce grabber of the update */
  287.                     SGUpdate(theSG, nil);
  288.                     EraseVideo(theSG, theWindow, videoChannel);
  289.  
  290.                     BeginUpdate(theWindow);
  291.                     EndUpdate(theWindow);
  292.                         /*and swallow the update event */
  293.                 }
  294.                 break;
  295.             
  296.             case mouseDown:
  297.                 part = FindWindow(theEvent.where,
  298.                                             &whichWindow);
  299.                 switch(part) {
  300.                     case inSysWindow:
  301.                         SystemClick(&theEvent, whichWindow);
  302.                         break;
  303.                     case inMenuBar:
  304.                         DoCommand(MenuSelect(theEvent.where));    
  305.                     case inContent:
  306.                         /* pause until mouse button is released */
  307.                         SGPause(theSG, true);
  308.                         while (StillDown())
  309.                         ;
  310.                         SGPause(theSG, false);
  311.                         EraseVideo(theSG, theWindow, videoChannel);
  312.                         break;
  313.                     case inGoAway:
  314.                         done = TrackGoAway (theWindow, theEvent.where);
  315.                         break;
  316.                     case inDrag:
  317.                         /*pause when dragging window so video doesn't draw in
  318.                             the wrong place */
  319.                         SGPause (theSG, true);
  320.                         SGGetAlignmentProc(theSG, &alignProc);
  321.                         DragAlignedWindow(theWindow,
  322.                                             theEvent.where,
  323.                                             &qd.screenBits.bounds,
  324.                                             nil, &alignProc);
  325.                         SGPause(theSG, false);
  326.                         EraseVideo(theSG, theWindow, videoChannel);
  327.                         break;
  328.                 }
  329.                 break;
  330.             
  331.             case keyDown:
  332.             case autoKey:
  333.                     key = theEvent.message & charCodeMask;
  334.                     if (theEvent.modifiers & cmdKey)
  335.                         if (theEvent.what == keyDown)
  336.                             DoCommand(MenuKey(key));
  337.                     break;
  338.     
  339.         }
  340.     }
  341.         
  342.     /*clean up*/
  343.     SGStop (theSG);
  344.     CloseComponent(theSG);
  345.     DisposeWindow (theWindow);
  346. }
  347.  
  348. void DoCommand(long mResult)
  349. {
  350.     int theMenu;
  351.     short theItem;
  352.     Str255 daName;
  353.     GrafPtr saveThePort;
  354.  
  355.     theItem = LoWord(mResult);
  356.     theMenu = HiWord(mResult);
  357.  
  358.     switch (theMenu)
  359.     {
  360.         case appleID:
  361.             if (theItem == aboutMeCommand)
  362.                 ShowAboutMeDialog();
  363.             else
  364.             {
  365.                 GetMenuItemText(mymenu0, theItem, daName);
  366.                 GetPort(&saveThePort);
  367.                 (void)OpenDeskAcc(daName);
  368.                 SetPort(saveThePort);
  369.             }
  370.             break;
  371.  
  372.         case fileID:
  373.             switch (theItem)
  374.             {
  375.                 case textCommand:
  376.                     showString = 1 - showString;
  377.                     menuKey = true;
  378.                     EraseVideo(theSG, theWindow, videoChannel);
  379.                     break;
  380.                 case quitCommand:
  381.                     done = true;
  382.                     break;
  383.                 default:
  384.                     break;
  385.             }
  386.             break;
  387.     }
  388.     HiliteMenu(0);
  389.     return;
  390. }
  391.     
  392.  
  393. SeqGrabComponent makeSequenceGrabber (WindowPtr aWindow)
  394. {
  395.     SeqGrabComponent anSG;
  396.     OSErr err = noErr;
  397.     
  398.     /* open up the default sequence grabber */
  399.     anSG = OpenDefaultComponent (SeqGrabComponentType, 0);
  400.     if (anSG) {
  401.             /* initialize the default sequence grabber component */
  402.         err = SGInitialize(anSG);
  403.         if (!err ) {
  404.             /* set the sequence grabber's graphics world to the 
  405.                 specified window */
  406.             err = SGSetGWorld (anSG, (CGrafPtr) aWindow, nil);
  407.         }
  408.     }
  409.  
  410.     if (err && anSG) {
  411.         /* clean up on failure */
  412.         CloseComponent(anSG);
  413.         anSG = nil;
  414.     }
  415.     return anSG;
  416. }
  417.  
  418. void makeGrabChannels (SeqGrabComponent anSG,
  419.                         SGChannel *videoChannel,
  420.                         SGChannel *soundChannel,
  421.                         const Rect *bounds, Boolean willRecord)
  422. {
  423.     OSErr    err;
  424.     long    usage;
  425.     /*figure out th usage */
  426.     
  427.     usage = seqGrabPreview;
  428.     if(willRecord)
  429.         usage |= seqGrabRecord;
  430.     /* create a video channel */
  431.     err = SGNewChannel (anSG, VideoMediaType, videoChannel);
  432.     if(!err) {
  433.     
  434.     /* set boundries for new video channel */
  435.         err = SGSetChannelBounds (*videoChannel, bounds);
  436.     
  437.     /*set usage for new video channel */
  438.         if(!err)
  439.             err = SGSetChannelUsage (*videoChannel,
  440.                                         usage | seqGrabPlayDuringRecord);
  441.             
  442.         if(err) {
  443.                 /* clean up on failure */
  444.                 SGDisposeChannel(anSG, *videoChannel);
  445.                 *videoChannel = nil;
  446.         }
  447.     }
  448.     
  449.     /* create a sound channel */
  450.     err = SGNewChannel (anSG, SoundMediaType, soundChannel);
  451.     if(!err){
  452.         /*set usage of new sound channel */
  453.         err = SGSetChannelUsage (*soundChannel, usage);
  454.         if(err){
  455.             /* clean up on failure */
  456.             SGDisposeChannel(anSG, *soundChannel);
  457.             *soundChannel = nil;
  458.         }
  459.     }
  460. }
  461.  
  462.  
  463. void EraseVideo(SeqGrabComponent aSG, WindowPtr aWindow, SGChannel theChannel)
  464. {
  465.     GrafPtr                        savePort;
  466.     GDHandle                    saveGD;
  467.     RGBColor                    oldColor, rgb, myRGBColor;
  468.     VideoDigitizerComponent        aVDIG;
  469.     long                        index;
  470.     OSErr                        error;
  471.  
  472.     aVDIG = SGGetVideoDigitizerComponent(theChannel);        
  473.     error = VDGetKeyColor(aVDIG, &index);
  474.     if(error == noErr){
  475.         
  476.         /* yellow is the color for the text on display */    
  477.         myRGBColor.red = 0xFC00;
  478.         myRGBColor.green = 0xF37D;
  479.         myRGBColor.blue = 0x052F;
  480.     
  481.         GetPort(&savePort);
  482.         saveGD = GetGDevice();
  483.         SetGDevice(GetMainDevice());
  484.         SetPort(aWindow);
  485.     
  486.         if(!showString && menuKey){
  487.     
  488.                 Index2Color(index, &rgb);
  489.                 GetForeColor(&oldColor);
  490.                 RGBForeColor(&rgb);
  491.                 PaintRect(&((GrafPtr) aWindow)->portRect);
  492.                 RGBForeColor(&oldColor);
  493.                 menuKey = false;
  494.  
  495.         }
  496.         
  497.         if(showString){
  498.     
  499.             MoveTo (30,30);
  500.             TextFont (applFont);
  501.             TextSize (14);
  502.             RGBForeColor(&myRGBColor);
  503.             DrawString("\pCupertino News");    
  504.         }
  505.  
  506.         SetPort(savePort);
  507.         SetGDevice(saveGD);
  508.     }
  509.     else
  510.     {
  511.             /* can not find the key color, let's us bail */
  512.             SysBeep(10);
  513.             Alert(129, nil);        
  514.             done = true;
  515.     }
  516.     
  517. }
  518.  
  519.